package com.zmc.product.application.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmc.common.annotation.PreventRepeatSubmit;
import com.zmc.common.domain.es.EsSkuEntity;
import com.zmc.common.domain.query.goods.GoodSkuSearchFeignQuery;
import com.zmc.common.domain.vo.inventory.InventoryInitVo;
import com.zmc.common.enums.RequestSourceEnum;
import com.zmc.common.enums.SerialCodeEnum;
import com.zmc.common.exception.base.BusinessException;
import com.zmc.common.utils.JsonUtils;
import com.zmc.common.utils.PageUtils;
import com.zmc.common.utils.R;
import com.zmc.common.utils.token.AuthTokenService;
import com.zmc.common.utils.uuid.IdUtils;
import com.zmc.common.utils.uuid.SnowflakeIdUtils;
import com.zmc.product.application.GoodsSkuApplicationService;
import com.zmc.product.feign.SearchFeignService;
import com.zmc.product.infrastructure.bean.query.CommodityGoodsSkuQuery;
import com.zmc.product.infrastructure.bean.vo.GoodSkuVo;
import com.zmc.product.infrastructure.bean.vo.PropertyValueVo;
import com.zmc.product.infrastructure.entity.CommodityCategoryEntity;
import com.zmc.product.infrastructure.entity.CommodityGoodsEntity;
import com.zmc.product.infrastructure.entity.CommodityGoodsSkuEntity;
import com.zmc.product.infrastructure.entity.CommodityGoodsSkuPropertyValueEntity;
import com.zmc.product.infrastructure.service.*;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：zmc
 * @Date：2024/12/9 14:07
 */
@Component
public class GoodsSkuApplicationServiceImpl implements GoodsSkuApplicationService {

    @Autowired
    private CommodityCategoryService commodityCategoryService;

    @Autowired
    private CommodityGoodsSkuService commodityGoodsSkuService;

    @Autowired
    private CommodityGoodsService commodityGoodsService;

    @Autowired
    private AuthTokenService authTokenService;

    @Autowired
    private InventoryGoodsStockService inventoryGoodsStockService;

    @Autowired
    private SearchFeignService searchFeignService;

    @Autowired
    private CommodityCategoryPropertyValueService commodityCategoryPropertyValueService;

    @Autowired
    private CommodityGoodsSkuPropertyValueService commodityGoodsSkuPropertyValueService;


    @Override
    public R pageCommodityGoodsSkuList(CommodityGoodsSkuQuery query) {
        Page<CommodityGoodsSkuEntity> page = commodityGoodsSkuService.pageCommodityGoodsSkuList(query);
        List<CommodityGoodsSkuEntity> records = page.getRecords();
        Map<String, Object> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            List<String> spuIds = records.stream().map(CommodityGoodsSkuEntity::getSpuId).collect(Collectors.toList());
            List<CommodityGoodsEntity> goods = commodityGoodsService.listBySpuIds(spuIds);
            records.forEach(sku -> {
                goods.stream().filter(spu ->spu.getSpuId().equals(sku.getSpuId())).findFirst().ifPresent(goodsEntity -> {
                    //sku列表框，展示每个sku名称
                    sku.setName(goodsEntity.getName());
                    //spu详情
                    if (map.isEmpty() && query.getSpuId() != null && query.getSpuId().equals(goodsEntity.getSpuId())) {
                        map.put("name", goodsEntity.getName());
                        map.put("goodStatus", goodsEntity.getStatus());
                    }
                });
            });
        } else if (query.getSpuId() != null){
            CommodityGoodsEntity goodsEntity = commodityGoodsService.getBySpuId(query.getSpuId());
            map.put("name", goodsEntity.getName());
            map.put("goodStatus", goodsEntity.getStatus());
        }
        R r = R.page(new PageUtils(page));
        r.putAll(map);
        return r;
    }

    @Override
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void saveSku(GoodSkuVo vo) {
        CommodityGoodsEntity goodsEntity = commodityGoodsService.getBySpuId(vo.getSpuId());
        CommodityCategoryEntity category = commodityCategoryService.getById(goodsEntity.getCategoryId());
        Integer skuLimit = category.getSkuLimit();
        Long count = commodityGoodsSkuService.countBySpuId(vo.getSpuId());
        if (skuLimit == null || count >= skuLimit) {
            throw new BusinessException("已超出sku阈值设置，无法添加");
        }
        CommodityGoodsSkuEntity skuEntity = new CommodityGoodsSkuEntity();
        BeanUtils.copyProperties(vo, skuEntity);
        skuEntity.setSkuId(SnowflakeIdUtils.nextSnowFlackId(authTokenService.getUserInfo().getPhone()));
        skuEntity.setSaleProperties(getSkuSaleValue(vo.getSkuValueList(), goodsEntity.getCategoryId()));
        commodityGoodsSkuService.save(skuEntity);
        //更新sku属性值
        vo.setId(skuEntity.getId());
        batchSaveSkuPropertyValue(vo);
        commodityGoodsService.goodToEditStatus(vo.getSpuId());
        //初始化库存中心库存
        InventoryInitVo inventoryInitVo = new InventoryInitVo();
        inventoryInitVo.setSkuId(skuEntity.getSkuId());
        inventoryGoodsStockService.saveInventory(inventoryInitVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void updateSkuById(GoodSkuVo vo) {
        CommodityGoodsSkuEntity skuEntity = new CommodityGoodsSkuEntity();
        BeanUtils.copyProperties(vo, skuEntity);
        CommodityGoodsEntity goodsEntity = commodityGoodsService.getBySpuId(vo.getSpuId());
        skuEntity.setSaleProperties(getSkuSaleValue(vo.getSkuValueList(), goodsEntity.getCategoryId()));
        String username = authTokenService.getUserInfo().getUsername();
        skuEntity.setUpdateBy(username);
        commodityGoodsSkuService.updateById(skuEntity);
        commodityGoodsSkuPropertyValueService.removeByGoodsSkuId(skuEntity.getSkuId());
        //更新sku属性值
        batchSaveSkuPropertyValue(vo);
        //检查商品状态
        commodityGoodsService.goodToEditStatus(vo.getSpuId());
    }

    @Override
    @Transactional
    public void removeGoodsSku(String skuId) {
        CommodityGoodsSkuEntity skuEntity = commodityGoodsSkuService.getBySkuId(skuId);
        commodityGoodsSkuService.removeBySkuId(skuId);
        //删除sku后，商品必须回到待审状态
        commodityGoodsService.goodToEditStatus(skuEntity.getSpuId());
        //删除sku
        commodityGoodsSkuService.removeById(skuId);
        //删除sku设定属性值
        commodityGoodsSkuPropertyValueService.removeByGoodsSkuId(skuId);
        //删除对应库存中心库存
        inventoryGoodsStockService.deleteBySkuId(skuId);
        //todo 若为自营商户，wms暂时不予处理，否则会造成数据不一致(后面分用户类型一起处理)
    }

    @Override
    public String getSkuNameBySkuId(String skuId) {
        CommodityGoodsSkuEntity skuEntity = commodityGoodsSkuService.getBySkuId(skuId);
        CommodityGoodsEntity goodsEntity = commodityGoodsService.getBySpuId(skuEntity.getSpuId());
        return goodsEntity.getName();
    }

    @Override
    public PageUtils search(GoodSkuSearchFeignQuery query) {
        return JsonUtils.transToArrayClassPage(searchFeignService.skuSearch(query), EsSkuEntity.class);
    }

    /**
     *
     * 批量存储sku属性值
     * */

    @Transactional
    public void batchSaveSkuPropertyValue(GoodSkuVo vo) {
        List<CommodityGoodsSkuPropertyValueEntity> list = new ArrayList<>();
        CommodityGoodsEntity goodsEntity = commodityGoodsService.getBySpuId(vo.getSpuId());
        List<PropertyValueVo> propertyValueVoList = commodityCategoryPropertyValueService.getGoodsSkuPropertyValueListByCategoryIdAndType(goodsEntity.getCategoryId());
        List<String> skuValueList = vo.getSkuValueList();
        for (int i = 0; i < propertyValueVoList.size(); i++) {
            PropertyValueVo valueVo = propertyValueVoList.get(i);
            String value = skuValueList.get(i);
            CommodityGoodsSkuPropertyValueEntity entity = new CommodityGoodsSkuPropertyValueEntity();
            entity.setSkuId(vo.getSkuId());
            entity.setCategoryPropertyValueId(Long.parseLong(valueVo.getPropertyValueId()));
            entity.setPropertyValue(value);
            list.add(entity);
        }
        commodityGoodsSkuPropertyValueService.saveBatch(list);
    }

    /**
     *
     * sku属性设置：格式为key1:value1,key2:value2...
     * */
    private String getSkuSaleValue(List<String> skuValueList, Long categoryId) {
        List<String> valueList = new ArrayList<>();
        List<PropertyValueVo> list = commodityCategoryPropertyValueService.getGoodsSkuPropertyValueListByCategoryIdAndType(categoryId);
        for (int i = 0; i < list.size(); i++) {
            valueList.add(list.get(i).getPropertyValue() + ":" + skuValueList.get(i));
        }
        return String.join(",", valueList);
    }
}
